package com.yu.thread6;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * Created by xiaolongyu on 15/3/21.
 */
public class Interrupting {
    private static ExecutorService exec = Executors.newCachedThreadPool();

    public static void test(Runnable r) throws InterruptedException {
        System.out.println("Interruption " + r.getClass().getName());
        Future<?> f = exec.submit(r);
        TimeUnit.MILLISECONDS.sleep(100);
        f.cancel(true);
        System.out.println("Interrupt to " + r.getClass().getName() + " " + System.currentTimeMillis());
        TimeUnit.SECONDS.sleep(20);
        System.out.println("---Exit");
    }

    public static void main(String[] args) throws InterruptedException {
        test(new SleepBlocked());
        test(new IOBlocked(System.in));
        test(new SynchronizedBlocked());
        TimeUnit.SECONDS.sleep(3);
        System.out.println("Aborting with system.exit(0)");
        System.exit(0);
    }
}

class SleepBlocked implements Runnable {
    @Override
    public void run() {
        try {
            TimeUnit.SECONDS.sleep(100);
        } catch (InterruptedException e) {
            System.out.println("SleepBlocked InterruptException" + " " + System.currentTimeMillis());
        }
        System.out.println("Exiting SleepBlocked.run()" + " " + System.currentTimeMillis());
    }
}

class IOBlocked implements Runnable {
    private InputStream in;
    public IOBlocked(InputStream in){
        this.in = in;
    }
    @Override
    public void run() {
        System.out.println("Waiting for read();");
        try {
            in.read();
        } catch (IOException e) {
            System.out.println("Interrupted from blocked I/O" + " " + System.currentTimeMillis() + " " + Thread.currentThread().isInterrupted());
            if(Thread.currentThread().isInterrupted()){
                System.out.println("Interrupted from blocked I/O" + " " + System.currentTimeMillis() + " " + Thread.currentThread().isInterrupted());
            } else {
                throw new RuntimeException();
            }
        }
        System.out.println("Exiting IOBlocked.run()" + " " + System.currentTimeMillis());
    }
}

class SynchronizedBlocked implements Runnable {

    public synchronized void f(){
        while (true){
            Thread.yield();
        }
    }

    public SynchronizedBlocked(){
        new Thread(){
            @Override
            public void run() {
                System.out.println("构造函数中运行" + " " + System.currentTimeMillis());
                f();
            }
        }.start();
    }

    @Override
    public void run() {
        System.out.println("Tying to call f()" + " " + System.currentTimeMillis());
        f();
        System.out.println("Exiting SynchronizedBlocked.run()" + " " + System.currentTimeMillis());
    }
}
